/**
 * 判断字符串和数组的长度是否为空，true表示空
 * @param target object对象
 * @returns {boolean}
 * * @private
 */
function _isEmpty(target) {
    if (target === undefined || target === null)
        return true;
    var type = Object.prototype.toString.call(target);
    if (type === '[object String]'){
        return target.length <= 0 ? true:false;
    }else if (type === '[object Array]'){
        return target.length <= 0 ? true:false;
    }
    return true;
}

function _isString(target) {
    var type = Object.prototype.toString.call(target);
    return type === '[object String]';
}

function _isArray(target) {
    var type = Object.prototype.toString.call(target);
    return type === '[object Array]';
}

/**
 * 判断传入的id和class是否合法 即开头有无‘#’或者‘.’和name不为空或空格
 * @param selector
 * @returns {boolean}
 * @private
 */
function _isClassOrId(selector) {
    var rex = /^((#)|(\.))\S+/
    return rex.test(selector);
}

/**
 *
 * @param selector
 * @param method
 * @private
 */
function _verifyselector(selector, method) {
    if (_isEmpty(selector)){
        _logError(method+' need an args which name selector');
        return false;
    }
    if (!_isClassOrId(selector)){
        _logError('dom element selector :'+selector + '不符合id或class命名规范');
        return false;
    }
    if (!$(selector)){
        _logError('dom element selector: '+selector+'not found');
    }
    return true;
}

/**
 *
 * @param str 打印日志字符串
 * @private
 */
function _logError(str) {
    console.error(str)
}

function _logWarn(str) {
   console.warn(str)
}

function _logInfo(str) {
   console.log(str)
}

/**
 * 获取表单数据，返回一个表单对象，根据name作为key
 * @param selector class(.**)或者id(#xxx)
 * @returns {FormData 对象}
 * @private
 */
function _getFormData(selector,excludes_name) {
    if (!_verifyselector(selector,'_getFormData'))
        return;
    var childrens;
    childrens = $(selector).find('[name]');//获取有name属性的children
    
    //过滤忽略的name的元素
    childrens = _filterExcludesName(excludes_name,childrens);
    
    if(!childrens || childrens.length <= 0)
        _logWarn(selector+'表单拥有name属性的子元素为空');
    var formData = new FormData();
    var key='';
    var value='';
    var item;
    for (var i = 0; i < childrens.length; i++) {
        item = childrens[i];
        var _type = item.type;
        if ((_type === 'radio' || _type === 'checkbox') && !(item.checked))//跳过未勾选的单选和多选
            continue;
        if (item){
            key = item.name;
            value = item.value;
            if (_isEmpty(value))//跳过没输入内容的文本
                continue;
            if (_type === 'checkbox'){//多选框是拼接
                var formDataEntryValue = formData.get(key);
                _isEmpty(formDataEntryValue) ? formData.append(key,value) : formData.set(key,formDataEntryValue+','+value);
            }else if (_type === 'file'){
                formData.append(key,item.files);
            } else{
                formData.append(key,value);
            }
        }
    }
    return formData;
}

/**
 * 获取表单数据,返回一个obj，根据name生成对象，可生成复杂对象
 * @param selector class(.**)或者id(#xxx)
 * @param excludes_name 需要忽略的name 可数组可对象，value可以是具体name或正则表达式
 * @returns {jsonObj 对象}
 * @private
 */

function _filterExcludesName(excludes_name,childrens){
	//过滤忽略的name的元素
	var rex;
    var _filters = [];
    if(_isArray(excludes_name)){
    	var item;
    	for (var i = 0; i < childrens.length; i++) {
    		item = childrens[i];
    		for (var j = 0; j < excludes_name.length; j++) {
    			rex = new RegExp(excludes_name[j]);
    			if(item != rex && !(rex.test(item.name))){
    				_filters.push(item);
    			}else{
    				break;
    			}
    		}
    	}
    }else {
    	rex = new RegExp(excludes_name);
		for (var j = 0; j < childrens.length; j++) {
			if(childrens[j].name != excludes_name && !(rex.test(childrens[j].name))){
				_filters.push(childrens[j]);
			}			
		}
    }
    return _filters;
}

function _getFormJson(selector,excludes_name) {
    if (!_verifyselector(selector,'_getFormJson'))
        return;
    var childrens;
    childrens = $(selector).find('[name]');//获取有name属性的children
    //过滤忽略的name的元素
    childrens = _filterExcludesName(excludes_name,childrens);
    if(!childrens || childrens.length <= 0)
        _logWarn(selector+'表单拥有name属性的子元素为空');
    var jsonObj = {};
    var key='';
    var value='';
    var item;
    for (var i = 0; i < childrens.length; i++) {
        item = childrens[i];
        var _type = item.type;
        if ((_type === 'radio' || _type === 'checkbox') && !(item.checked))//跳过未勾选的单选和多选
            continue;
        if (item){
            key = item.name;
            value = item.value;
            if (_isEmpty(value))//跳过没输入内容的文本
                continue;
            var keys =[];
            keys = key.split('.');//例如user.name
            var pro = jsonObj;
            for (var j = 0; j < keys.length; j++) {
                if (j < keys.length - 1){
                    var _temp = pro[keys[j]];
                    pro = pro[keys[j]] = (!_temp) ? {}:_temp;
                }
                else{
                    if (_type === 'checkbox')//多选框是拼接
                        _isEmpty(pro[keys[j]]) ? pro[keys[j]] = value : pro[keys[j]] += ','+value;
                    else if (_type === 'file')
                        pro[keys[j]] = item.files;
                    else
                        pro[keys[j]] =  pro[keys[j]] ? pro[keys[j]]+','+value : value;
                }
            }
        }
    }

    return jsonObj;
}

/**
 * 将对象绑定到dom元素上 根据 dom 元素的name属性
 * @param selector dom
 * @model 要显示的 model
 * @private
 */
function _object2Dom(selector,model) {
    if (!_verifyselector(selector,'_object2Dom'))
        return;
    var childrens = $(selector).find('[name]');
    var item,tagname,key,value;
    for (var i = 0; i < childrens.length; i++) {
        item = childrens[i];
        tagname = item.tagName.toLowerCase();
        key = $(item).attr('name');
        value = _mapGetValue(key,model);
        switch (tagname) {
            case 'input':
                var _type = item.type;
                switch (_type) {
                    case 'radio':
                        var _v = item.value;
                        item.checked = value === _v ? true : false;
                        break;
                    case 'checkbox':
                        var _v = item.value;
                        if (_isArray(value)){
                            for (var j = 0; j < value.length; j++) {
                                if (value[j] === _v){
                                    item.checked = true;
                                    break;
                                }else {
                                    item.checked = false;
                                }
                            }
                        }else if (_isString(value)){
                            var _split = value.split(',');
                            for (var j = 0; j < _split.length; j++) {
                                if (_split[j] === _v){
                                    item.checked = true;
                                    break;
                                }else {
                                    item.checked = false;
                                }
                            }
                        }else {
                            _logError('请确认复选框的参数是数组或者是逗号隔开的如： a,b,c  字符串形式')
                        }
                        break;
                    case 'file':
                        break;
                    default:
                        item.value = value;

                }
                break;
            case 'textarea':
                item.value = value;
                break;
            case 'select':
                var _childs = $(item).find('[value]');
                var _item;
                for (var j = 0; j < _childs.length; j++) {
                    _item = _childs[j];
                    _item.selected = _item.value === value ? true : false;
                }
                break;
            case 'img':
                item.src = value;
                break;
            default:
                item.innerText = value;
        }
    }
}

/**
 * 清除表单
 * @param selector
 * @param _default  true（下拉和單選是否有默認勾選,默認勾選第一個）
 * @private
 */
function _clearForm(selector,_default,excludes_name) {
    if (!_verifyselector(selector,'_clearForm'))
        return;
    var childrens = $(selector).find('[name]');
    //过滤忽略的name的元素
    childrens = _filterExcludesName(excludes_name,childrens);
    var item,type,tagname;
    for (var i = 0; i < childrens.length; i++) {
        item = childrens[i];
        tagname = item.tagName.toLowerCase();
        switch (tagname) {
            case 'input':
                type = item.type;
                switch (type) {
                    case 'radio':
                        item.checked = false;
                        if (_default) {
                            var childs = [];
                            for (var j = 0; j < childrens.length; j++) {
                                var flag =  childrens[j].name === item.name ? true : false;
                                if (flag)
                                    childs.push(childrens[j])
                            }
                            for (var j = 0; j < childs.length; j++) {
                                if (j >= childs.length - 1)
                                    childs[0].checked = true;
                                else
                                    childs[j].checked = false;
                            }
                        }
                        break;
                    case 'checkbox':
                        item.checked = false;
                        break;
                    case 'file':
                        item.value = '';
                        break;
                    default:
                        item.value = '';
                }
                break;
            case 'select':
                item.value = '';
                if (_default){
                    var childs = $(item).find('[value]');
                    for (var j = 0; j < childs.length; j++) {
                        if (j === 0){
                            childs[j].selected = true;
                            break;
                        }
                    }
                }
                break;
            case 'textarea':
                item.value = '';
                break;
            case 'img':
                item.src = '';
                break;
            default:
                item.innerText = '';
        }

    }
}


/**
 * 將字符串html填充到指定元素，需重寫fn方法
 * @param selector
 * @param arr
 * @param callback 不要漏了item
 * @private
 */
/*
* var list = ['football','basketball','table tennis','running'];
    _appendDomList('#uu',list,function (item) {
        return `<li><span>${item}</span></li>`;
    })
*/
function _appendDomList(selector, arr, callback) {
    if (!_verifyselector(selector,'_appendDomList'))
        return;
    if (!_isArray(arr)){
        _logError('_appendDomList args which name arr must an Array');
        return;
    }
    var item,_html;
    var $selector = $(selector);
    for (var i = 0; i < arr.length; i++){
        item = arr[i];
        _html = callback(item);// => 不要漏了item
        $(_html).appendTo($selector);
    }
}

/***
 * 获取指定容器name= name_value 的value
 * @param {Object} selector
 * @param {Object} name_value 指定name名称
 */
function _getEqNameValue(selector,name_value) {
    if (!_verifyselector(selector,'_getEqNameValue'))
        return;
    var childrens = $(selector).find('[name="'+name_value+'"]');
    var strs = '';
    var item;
    for (var i = 0; i < childrens.length; i++) {
		item = childrens[i];
		if(i === 0)
			strs = item.value;
		else
			strs += ','+item.value;
    }
    return strs;
}

function _mapGetValue(key, obj) {
    var keys = key.split('.');
    var _obj = obj;
    for (var i = 0; i < keys.length; i++) {
        _obj = _obj[keys[i].trim()];
        if (!_obj){
            _logError('該對象沒有'+key+'鍵值對');
            _logError(obj);
            break;
        }

    }
    return _obj ? _obj : _blank();
}


function _blank() {
    return '';
}



